13. 모델링: 클래스 설계의 토대

📌 Contents

  • 모델: 동작 원리와 구조를 간단하게 설명하기 위해, 사물의 특징과 관계를 그림으로 나타낸 것
  • 모델링: 모델을 만드는 활동

📌 악마를 불러들이기 쉬운 User 클래스

  • 로그인 사용자를 나타내는 User 클래스는 사양 변경이 굉장히 잦아서, 여러가지 문제를 일으키기 쉬움
  • User 클래스에는 ID, 이름, 이메일주소, 비밀번호 등이 있음
  • User 클래스에 법인 관련 사양 등 다양한 사양이 추가되고, 로그인 사용자를 등록하고 관리하는 UserManager 클래스와 법인 사용자를 등록하고 관리하는 CorporationManager 클래스를 만들게 된다면,
  • 일반 로그인 사용자와 법인 사용자의 사양이 달라, NullPointerException이나 여러 유효성 검사와 관련된 오류가 발생하는 코드가 되버림
  • 이러한 문제가 발생하는 이유는 모델링을 제대로 하지 않았기 때문임

📌 모델링으로 접근해야 하는 구조

  • 모델은 시스템의 구조를 설명하기 위해서 사용
  • 모델링을 이해하려면, 일단 시스템이 무엇인지 이해해야 함

시스템이란?

  • 시스템의 사전적 정의: 수많은 구성 요소로 이루어진 집합체로서, 각각의 부분이 유기적으로 연결되어, 전체적으로 하나의 목적을 갖고 움직이는 것
  • 다양한 사회적 활동은 각각의 시스템에 의해 굴러감
    • 목적지로 이동할 때: 두 다리를 번갈아 움직이면서 이동하는 '이족 보행 시스템' 사용
    • 의사소통할 때: "음파를 통한 회화 시스템" 사용
  • 인류는 다양한 도구와 기계를 발명함
    • 목적지로 이동하기 위해 마차, 자동차, 비행기 등을 발명
    • 의사소통을 하기 위해 편지, 전화, SNS 등을 발명
  • 목적 달성을 더 효율적으로 하기 위해서 또 다른 시스템을 만들어 냄
  • 시스템은 목적 달성을 위한 수단. 기술의 본질은 능력을 확정 하는 것
  • 시스템 중에서 컴퓨터를 활용하는 시스템을 정보 시스템이라고 부름

시스템 구조와 모델링

  • 세상에 있는 편리한 시스템들은 특징적인 구조를 갖고 있음
  • 모델은 이러한 시스템의 구조를 설명하기 위해 사용됨
  • 시스템 구조를 설명하기 위해 단순한 상자로 도식화한 것이 모델임
  • 모델의 의도를 정의하고, 구조를 설계하는 것이 모델링임


  • 시스템은 목적을 달성하기 위한 수단
  • 모델은 시스템의 구성요소들
  • 즉, 모델은 목적을 달성하기 위한 수단의 일부를 개념화한 것
  • 정리하면, 모델이란 특정 목적 달성을 위해 최소한으로 필요한 요소를 갖춘 것

소프트웨어 설계와 모델링

  • 소프트웨어 설계에서의 모델은 어떨까? 온라인 쇼핑물을 예를 들어 생각해보자
  • 온라인 쇼핑몰은 상품 매매를 시스템화한 것
  • 상품을 모델로 나타내면, 상품명, 원가, 판매 가격, 제조년월일, 제조 업체, 구성 부품, 유통 기한 등 너무 많은 정보가 있음
  • 이 정보를 모두 포함하면 모델의 목적을 알 수 없음
  • 모델은 '특정 목적 달성을 위해서, 최소한으로 필요한 요소를 갖춘 것'이라고 했으니, 목적을 조금 더 자세하게 생각해보자
  • 주문 시 상품 모델을 만들기 위한 최소한으로 필요한 요소들은 상품 ID, 상품명, 판매 가격, 재고 수량 등이 있음
  • 배송 시 상품 모델을 만들기 위한 최소한으로 필요한 요소들은 상품 ID, 상품 크기, 상품 무게 등이 있음
  • 주문과 배송은 달성해야 하는 목적이 다름
  • 즉, 목적에 따라 상품의 모델이 달라짐

📌 안 좋은 모델의 문제점과 해결 방법

  • 앞서 말한 User 클래스의 법인 관련 사양 등은 개인 프로필과 관련이 없음
  • 이메일 주소와 비밀번호도 개인 프로필 관련 요소가 아닌 로그인 인증과 관련된 요소임
  • 즉, User 클래스(모델)는 '여러 목적에 무리하게 사용되고 있으며, 모델링된 것처럼 보이지만 모델링되어 있지 않다'라고 할 수 있음
  • 이런 모델을 일관성 없는 모델이라고 함
  • 모델링이 제대로 이루어지지 않으면, User 클래스처럼 여러 가지 문제의 원흉이 됨
  • 모델링을 잘하려면, 반드시 대상이 되는 사회적 활동과 목적을 이해해야 함

목적별로 모델링하기

  • 앞서 살펴본 상품과 사용자는 물리적인 세부 사항 등은 무시하고, 개념적인 측면만 가상 현실 세계에 투영한 모델이라 볼 수 있음
  • 사용자를 그대로 User로 모델링하면, 모델의 일관성 문제를 해결할 수 없음
  • 각각의 매체는 목적에 따라 표현 방법과 이름이 달라 모두 User라는 이름으로 표현될 수 없음
  • 따라서, 사용자를 표현하는 수단은 목적에 따라 이름과 형태가 달라짐
  • User 클래스는 목적에 따라, 프로필, 개인 계정, 법인 계정, 회사 개요, 직무 경험 등의 여러 개의 모델로 정의할 수 있음
  • 이처럼 정보 시스템에서는 '현실 세계에 있는 물리적인 존재'(사용자)와 '정보 시스템에 있는 모델'(프로필, 개인 계정, 법인 계정 등)이 무조건 일대일 대응이 아니라 일대다 대응되는 경우가 많음
  • 또한 User(사용자)라는 이름은 굉장히 애매모호함
  • 목적 중심 이름 설계처럼 구체적이고, 의미 범위가 좁고, 목적을 나타내는 이름으로 다시 설계하는 것도 좋음
    • 개인 로그인 인증: PersonalAccount
    • 법인 로그인 인증: CorporateAccount
    • 특징 표현: Profile

모델은 대상이 아니라 목적 달성의 수단

  • 모델링이 제대로 되지 않는 원인은 모델을 단순한 '대상'으로 해석하고 있기 때문
  • 모델을 단순한 '대상'으로 해석하면, 여기에 모든 목적이 담겨 데이터는 거대해질 수밖에 없고, 일관성 없는 구조가 됨
  • '목적 달성 수단으로의 모델'은 '목적 중심 이름 설계'와 관점이 같음
  • 목적 중심으로 이름을 잘 설계하면, 목적을 달성하기에 적절한 모델을 설계할 수 있음

단일 책임이란 단일 목적

  • 목적과 책임은 서로 대응되는 관계
  • 따라서 단일 책임 원칙은 단일 목적 원칙이라고도 할 수 있음
  • '클래스가 이루어야 하는 목적은 반드시 하나여야한다'라는 것임
  • 클래스를 '공통으로 사용 가능한 범용적인 부품으로 설계해야 한다'고 생각하는 사람도 있을 것임
  • 하지만, 특정 목적에 특화되게 설계해야, 변경하기 쉬운 고품질 구조를 갖게 됨
  • 목적을 먼저 확립해야 관심사에 따라 가져야 할 책임을 정할 수 있음

모델을 다시 확인하는 방법

  • 해당 모델이 달성하려는 목적을 모두 찾아내기
  • 목적별로 모델링을 다시 수정하기
  • 목적 중심 이름 설계를 기반으로 모델에 이름을 붙이기
  • 모델에 목적 이외의 요소가 들어가 있다면 다시 수정하기

모델과 구현은 반드시 서로 피드백하기

  • 모델은 구조를 단순화한 것에 불과하므로, 세부적인 내용은 따로 묘사하지 않음
  • 따라서 모델을 기반으로 클래스를 설계하고, 코드를 구현하면서 세부적인 내용을 수정해야 함
  • '모델 = 클래스'가 아님. 일반적으로 모델 하나는 여러 개의 클래스로 구현됨
  • 따라서 모델을 클래스와 코드로 정교화하는 단계에서, 동작에 필수적인 요소들을 간과했음을 깨닫는 경우가 많음
  • 클래스 설계와 구현에서 무언가를 깨닫는다면, 이를 모델에 피드백해야함
  • 피드백을 하면 모델이 더 정확해지고, 그러면 모델 구조를 개선할 수 있고, 개선된 모델은 마찬가지로 클래스와 코드 품질 향상에 기여함

📌 기능성을 좌우하는 모델링

  • 기능성이란 소프트웨어의 품질 특성 중 하나로, '고객의 니즈를 만족하는 정도'를 의미

숨어 있는 목적 파악하기

  • 온라인 쇼핑몰에서 상품 구매 모델링을 생각해 볼때, 매매 개약의 법적인 내용이 시스템에 반영되어 있지 않다면,
  • 판매자와 구매자에게 어떤 문제가 생겼을 때, 법적인 효력을 갖지 못해 현실의 문제를 해결하지 못하는 시스템이 될 수 있음
  • 기능을 제대로 발휘하려면, '개념의 정체'와 '뒤에 숨어 있는 중요한 목적'을 잘 파악해야함

기능성을 혁신하는 '깊은 모델'

  • 모델을 목적 달성 수단으로 해석하면, 추상화했을 때 모델의 확장성이 커짐
  • 같은 목적 달성 수단이라고 해도, 구조에 따라 달성 효율이 다름. 구조를 개선하여 기능을 혁신할 수 있음
  • 소프트웨어 분야에도 다양한 혁신이 있음
    • 트위터: 정보 확산이라는 기능성이 기존의 방식(게시판, 이메일, 블로그 등)보다 훨씬 높음. - 정보 확산 수단
  • 좋은 구조는 변환 능력을 갖고 있음
    • 리트윗을 정보 확산 수단의 모델로 해석하면, 리트윗은 팔로워의 타임라인을 변환하는 능력을 갖고 있음
  • 컴퓨터의 본질은 '0과 1이라는 신호를 변환'하고, '신호 변환을 응용해서 연산하는 것'이라 할 수 있음
  • 뛰어난 변환 능력을 갖춘 모델을 설계하는 것이 곧 기능성의 혁신으로 이어짐
  • 도메인 주도 설계에서는 이처럼 '본질적 과제를 해결하고, 기능성 혁신에 공헌하는 모델'을 깊은 모델(deep model)이라고 부름

Note

깊은 모델은 하루 아침에 만들어지지 않습니다.
수많은 시행착오를 거듭하고, 모델을 계속해서 개량하는 과정에서 발상이 전환되고,
이 과정에서 기존의 한계를 극복할 수 있는 깊은 모델이 만들어지는 것입니다.
설계는 한 번 했다고 끝나는 것이 아니라, 매일매일 반복해서 개선하는 것이 중요합니다.

❓ Questions

❓ 목적이 다르면 무조건 분리해야 할까?

  • 클래스를 공통으로 사용 가능한 범용적인 부품으로 설계한다면, 코드를 재사용할 수 있어서 효율이 증가하고 가독성이 좋아질 것이다.
  • 하지만 책에서 나온대로 사양이 변경될때 변경하기 쉬운 구조를 갖기 위해서는 특정 목적에 특화되게 설계해야 한다.
  • 그러면 목적이 달라도 구조가 같고, 앞으로 사양이 변경하지 않을 것이라는 생각이 든다면 어떨까?
  • 실제로 클래스는 아니지만 진행중인 프로젝트에서 컴포넌트를 만들 때, 드롭다운 컴포넌트를 공용으로 만들어 프로필을 눌렀을 때 나오는 드롭다운, 설정을 눌렀을 때 나오는 드롭다운, 브랜치 선택을 위한 드롭다운에 사용되도록 만들었다.
  • 3가지 목적의 드롭다운이 모두 모양이 비슷해 props로 드롭다운 메뉴의 이름과 메뉴 클릭시 실행 함수를 배열에 담아서 전달해 주었다.
  • 드롭다운에 아이콘이 있는게 있고 없는 것이 있지만, 이 부분은 그냥 아이콘이 필요한 드롭다운만 아이콘을 같이 전달해서 아이콘이 전달되면 렌더링 되도록 하였다.
    • 여기서 아이콘이 있나 없나에 대한 분기 처리가 있긴 하지만, 그냥 아이콘이 있으면 넣고 없으면 안넣는다 라는 분기 처리가 이해하기 어렵거나 한다고 생각이 들지 않는다.
  • 이렇게 구현하다 보니까 복잡한 드롭다운을 3개 구현할 필요 없이 한 번만 구현한 뒤 재사용해서 효율도 좋았고 가독성도 좋아 잘 짰다는 생각이 든다.
  • 3가지 목적중에 한가지 목적의 드롭다운의 사양만 변경된다면 문제가 생기긴 할 것이다. 하지만 3가지 목적의 드롭다운 모두 사양을 변경할 생각은 없다.
  • 이런 상황에서도 목적에 따라 분리를 해야 할까?

❓ 좋은 모델의 뛰어난 변환 능력이 무엇을 말하는 것인가? 깊은 모델이 정확히 무엇일까?

  • 책에서는 트위터의 리트윗을 정보 확산 수단의 모델이면서, 팔로워의 타임라인을 변환하는 능력을 갖기 때문에 좋은 구조라고 한다.
  • 모니터는 케이블로부터 비트 신호를 받아 화소로 변환한다고 한다.
  • 온라인 쇼핑몰은 클릭 몇 번을 발주 데이터와 결제 데이터로 변환해 준다고 한다.
  • 이 3가지 예시의 변환 능력들이 비슷한 느낌을 주지 않는다. 너무 상황에 맞춰서 말하고 있는 느낌이다.
  • 컴퓨터의 본질은 '0과 1이라는 신호를 변환'하고, '신호 변환을 응용해서 연산 하는 것'이라고 책에 나오는데, 그럼 이 말은 컴퓨터가 좋은 구조를 가진 시스템이라는 것인가 아니면 컴퓨터를 이용해 만든 모델(온라인 쇼핑몰 등)이 좋은 구조를 가진 시스템이라는 말인가?
  • 그럼 컴퓨터 프로그램은 모두 다 좋은 구조인건가?
  • '본질적 과제를 해결하고, 기능성 혁신에 공헌하는 모델'이 깊은 모델이라고 했는데 여기서 본질적 과제가 정확히 뭐고, 깊은 모델이 정확히 무엇을 의미하는 것일까?

results matching ""

    No results matching ""